package site

import (
	"errors"
	"fmt"
	"hft/Database/admin"
	"hft/Http/Models/dao"
	"hft/Http/Services/base"
	sitedao "hft/Http/Services/site/site_dao"
	siterequest "hft/Http/Services/site/site_request"
	utils "hft/Http/Utils"
	"hft/e"
	"hft/global"
	"hft/tools"
	"time"

	"gorm.io/gorm"
)

// 站点操作
type Site struct{}

// 获取可以设置站点的账号
func (*Site) GetSiteAccountCanSet(paginate *siterequest.SiteReq) (data *utils.Page, err error) {

	var list = make([]*admin.Account, 0)

	global.OC_DB.Scopes(sitedao.SiteDao.List(paginate, global.OC_DB)).Find(&list).Scopes(dao.GetCount(global.OC_DB)).Count(&paginate.Total)

	paginate.Data = list

	return &paginate.Page, nil
}

// 设置站点
func (*Site) SetSite(req *siterequest.SetSite) (err error) {
	var region *admin.Region
	err = global.OC_DB.Where("level = ?", "city").First(&region, req.Region).Error
	if err != nil {
		return errors.New(e.RegionNotFound)
	}
	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {
		var oldManager *admin.Account
		if region.ManageId != 0 {
			tx.First(&oldManager, region.ManageId)
			res := tx.Model(&admin.Account{}).Where("id = ?", oldManager.ID).Updates(map[string]interface{}{"belong": 1, "region_link": ",1,"})
			if res.RowsAffected == 0 {
				return errors.New(e.AccountNotExist)
			}
			if res.Error != nil {
				return errors.New(e.ErrorInfo)
			}
		}

		res := tx.Model(&admin.Region{}).Where("id = ?", req.Region).Updates(map[string]interface{}{
			"manage_id": req.ID,
			"over_time": req.OverTime,
		})

		if res.RowsAffected == 0 {
			return errors.New(e.RegionNotFound)
		}
		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}
		res = tx.Model(&admin.Account{}).Where("id = ?", req.ID).Updates(map[string]interface{}{
			"belong":      region.ID,
			"region_link": fmt.Sprintf("%v%v,", region.Link, region.ID),
		})

		if res.RowsAffected == 0 {
			return errors.New(e.AccountNotExist)
		}
		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}

		// 创建配置
		err = sitedao.SetCityConfig(int(req.Region), tx)
		if err != nil {
			return err
		}

		// 创建友情链接模版
		err = sitedao.InitFriendlyLink(global.OC_DB, int(req.Region))
		if err != nil {
			return err
		}
		// 设置站点过期时间
		global.OC_REDIS.Set(fmt.Sprintf("SITE_LOGIN-%v", req.Region), req.ID, time.Duration(req.OverTime-int(time.Now().Unix())*int(time.Second)))
		return nil
	})
	if err != nil {
		return err
	}

	return nil
}

// 解绑站点与账号的关系
// 需要封禁该账号创建的所有的账号
func (*Site) ReleaseSite(req *siterequest.SetSite) (err error) {

	var account *admin.Account
	err = global.OC_DB.First(&account, req.ID).Error
	if err != nil {
		return errors.New(e.AccountNotExist)
	}
	var region *admin.Region
	err = global.OC_DB.First(&region, req.Region).Error
	if err != nil {
		return errors.New(e.RegionNotFound)
	}
	if region.ManageId != account.ID {
		return errors.New(e.SiteNotMatch)
	}
	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {

		res := tx.Model(&admin.Account{}).Where("id = ?", account.ID).Updates(map[string]interface{}{"belong": 1, "region_link": ",1,"})
		if res.RowsAffected == 0 {
			return errors.New(e.AccountNotExist)
		}
		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}
		res = tx.Model(&admin.Region{}).Where("id = ?", req.Region).Updates(map[string]interface{}{"manage_id": nil, "over_time": nil})
		if res.RowsAffected == 0 {
			return errors.New(e.RegionNotFound)
		}
		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}
		err = sitedao.SiteAccountDao.BanAllAccountBelongSite(account.AccountLink, int(account.ID), tx)
		if err != nil {
			return err
		}

		// 解绑redis站点
		global.OC_REDIS.Del(fmt.Sprintf("SITE_LOGIN-%v", region.ID))

		return nil
	})

	return err
}

// 获取账号的站点
func (*Site) GetSiteList(claims tools.BaseClaims) (list []*siterequest.SiteList, err error) {
	var siteList = make([]*siterequest.SiteList, 0)
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return nil, err
	}
	err = global.OC_DB.Model(&admin.Region{}).Where("manage_id = ?", account.ID).Scan(&siteList).Error
	if err != nil {
		return nil, errors.New(e.ErrorInfo)
	}

	return siteList, nil

}

// 设置账号登录的站点
func (*Site) SetNowSiteLogin(claims tools.BaseClaims, id int) (err error) {

	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	var region *admin.Region
	err = global.OC_DB.Where("manage_id = ?", account.ID).First(&region, id).Error
	if err != nil {
		return errors.New(e.NoRightToLoginThisSite)
	}
	res := global.OC_DB.Model(&admin.Account{}).Where("id = ?", account.ID).Updates(map[string]interface{}{
		"belong":      region.ID,
		"region_link": fmt.Sprintf("%v%v,", region.Link, region.ID),
	})
	if res.RowsAffected == 0 {
		return errors.New(e.AccountNotExist)
	}
	if res.Error != nil {
		return errors.New(e.ErrorInfo)
	}

	return nil
}

var SiteService = new(Site)
